﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Application.AppPlcManage;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Domain.GlobalClass;
using Zocono.WCS.Domain.PlcBytesObject;
using Zocono.WCS.Domain.PlcConnectPoolDomain;
using Zocono.WCS.Domain.ProcessModuleDomain;
using Zocono.WCS.Domain.ScGetWMSTaskDomain;
using Zocono.WCS.Domain.WcsGetWmsJobDomain;
using Zocono.WCS.Infrastructure.ApllicationDto.WCSTaskDto;

namespace Zocono.WCS.HangfireHost.Controllers
{
    /// <summary>
    /// 操作设备接口
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class WCSOperateEquipmentController : ControllerBase
    {
        private readonly PlcWriteBoMange _plcWriteBoMange;
        private readonly IPlcConnectionPoolService _plcConnectionPoolService;
        private readonly ILogUtil _logUtil;
        private readonly IScGetWMSTaskService _scGetWMSTaskService;
        private readonly IWcsGetWmsJobService _IWcsGetWmsJobService;

        public WCSOperateEquipmentController(IPlcConnectionPoolService plcConnectionPoolService, PlcWriteBoMange plcWriteBoMange, ILogUtil logUtil, IScGetWMSTaskService scGetWMSTaskService, IWcsGetWmsJobService wcsGetWmsJobService)
        {
            _plcConnectionPoolService = plcConnectionPoolService;
            _logUtil = logUtil;
            _scGetWMSTaskService = scGetWMSTaskService;
            _IWcsGetWmsJobService = wcsGetWmsJobService;
            this._plcWriteBoMange = plcWriteBoMange;
        }

        /// <summary>
        /// 复位报警信号
        /// </summary>
        /// <param name="equipmentCode"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        [HttpGet]
        public async Task WCSResetZJNScAlarmAsync(string equipmentCode)
        {
            try
            {

                //Sc写入Db
                PlcWriteDbInfo plcWriteDbInfo = await _scGetWMSTaskService.ScGetPlcWriteDbInfoAsync(equipmentCode, "ZJNScMessageWriteWcsActionBO");
                //Sc使用Plc连接
                var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);
                if (plcservice == null)
                {
                    throw new Exception($"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在");
                }
                byte[] bytes = await plcservice.ReadDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, 1);
                if (bytes != null)
                {
                    HelperByte.SetBitAt(ref bytes, 0, 1, true);
                    bool flag = await plcservice.WriteDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, bytes);

                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }


        //https://localhost:44371/api/WCSOperateEquipment/WCSGetWMSInitialWorkTask
        /// <summary>
        /// 获取下架（越库、移库、倒库）任务接口 
        /// </summary>
        /// <returns></returns>
        //[HttpPost]
        //public async Task<bool> WCSGetWMSInitialWorkTaskAsync(List<WmsTaskInfoDto> wmsTaskInfoDtos)
        //{
        //    try
        //    {
        //        if (wmsTaskInfoDtos.Count() > 0)
        //        {
        //            _logUtil.Info(JsonConvert.SerializeObject(wmsTaskInfoDtos)+ "获取下架（越库、移库、倒库）任务接口");
        //            await _IWcsGetWmsJobService.WCSGetWMSInitialWorkTaskAsync(wmsTaskInfoDtos);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        throw new Exception(ex.Message.ToString());
        //    }
        //}


        [HttpGet]
        public async Task WCSResetZJNSTaskAutomaticResetAsync(string equipmentCode)
        {
            try
            {
                //Sc写入Db
                PlcWriteDbInfo plcWriteDbInfo = await _scGetWMSTaskService.ScGetPlcWriteDbInfoAsync(equipmentCode, "ZJNScMessageWriteWcsActionBO");
                //Sc使用Plc连接
                var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);
                if (plcservice == null)
                {
                    throw new Exception($"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在");
                }
                //byte[] bytes = await plcservice.ReadDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, 1);
                //if (bytes != null)
                //{
                //    HelperByte.SetBitAt(ref bytes, 0, 2, true);
                //    bool flag = await plcservice.WriteDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, bytes);
                //}
                bool flag = await plcservice.WriteDbBitAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, 2, true);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }



        /// <summary>
        /// 复位报警信号
        /// </summary>
        /// <param name="equipmentCode"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        [HttpGet]
        public async Task WCSSetPlanerPLCAsync(string equipmentCode)
        {
            try
            {
                //Sc写入Db
                PlcWriteDbInfo plcWriteDbInfo = await _scGetWMSTaskService.ScGetPlcWriteDbInfoAsync(equipmentCode, "ZJNScMessageWriteWcsActionBO");
                //Sc使用Plc连接
                var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);
                if (plcservice == null)
                {
                    throw new Exception($"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在");
                }
                byte[] bytes = await plcservice.ReadDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, 1);
                if (bytes != null)
                {
                    HelperByte.SetBitAt(ref bytes, 0, 1, true);
                    bool flag = await plcservice.WriteDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, bytes);

                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }



        /// <summary>
        /// 写ScPLC
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<HeaderResult<bool>> OperateScWcsBoAsync(ZJNScMessageWriteWcsActionBO zjnScWcsBo)
        {
            HeaderResult<bool> result = new();
            if (zjnScWcsBo!=null)
            {
                ZJNScMessageWriteWcsActionBO zjnScBo = new()
                {
                    ObjectType = zjnScWcsBo.ObjectType,
                    Startcommand = zjnScWcsBo.Startcommand,
                    Alarmreset = zjnScWcsBo.Alarmreset,
                    WCSfirecommand = zjnScWcsBo.WCSfirecommand,
                    WCSPhotoFire = zjnScWcsBo.WCSPhotoFire,
                    WCSRgvFireHlper = zjnScWcsBo.WCSRgvFireHlper,
                    WCSDTSAlarm =zjnScWcsBo.WCSDTSAlarm,
                    TimeReset =zjnScWcsBo.TimeReset,
                    Taskreset = zjnScWcsBo.Taskreset,

                    Jobnumber = zjnScWcsBo.Jobnumber,
                    Jobordercode = zjnScWcsBo.Jobordercode,
                    WCSpostingcompleted = zjnScWcsBo.WCSpostingcompleted,
                    StartlinefromPC = zjnScWcsBo.StartlinefromPC,
                    TargetlinefromPC = zjnScWcsBo.TargetlinefromPC,
                    StartcolumnfromPC = zjnScWcsBo.StartcolumnfromPC,
                    TargetcolumnfromPC = zjnScWcsBo.TargetcolumnfromPC,
                    StartlayerfromPC = zjnScWcsBo.StartlayerfromPC,
                    TargetlayerfromPC = zjnScWcsBo.TargetlayerfromPC,
                    yuliu8 = zjnScWcsBo.yuliu8,
                    yuliu9 = zjnScWcsBo.yuliu9,
                    yuliu10 = zjnScWcsBo.yuliu10,
                    yuliu11 = zjnScWcsBo.yuliu11,
                    yuliu12 = zjnScWcsBo.yuliu12,

                    EquipmentCode = zjnScWcsBo.EquipmentCode,
                };
                try
                {
                    var res = await _plcWriteBoMange.WCSSetSCPLCAsync(zjnScBo);
                    if (res)
                    {
                        result.IsSucceed = true;
                        result.Message = "成功！";
                    }
                    else
                    {
                        result.IsSucceed = false;
                        result.Message = "失败！";

                    }
                }
                catch (Exception e)
                {
                    result.IsSucceed = false;
                    result.Message = e.Message;
                }
            }
            else
            {
               
                        result.IsSucceed = false;
                        result.Message = "失败！";
               
            }


            return result;
        }




        /// <summary>
        /// 写PlanarPLC
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<HeaderResult<bool>> OperatePlanarWcsBoAsync(PlanarGeneralWriteWcsAction planarWcsBo)
        {
            HeaderResult<bool> result = new();
            if (planarWcsBo != null)
            {
                PlanarGeneralWriteWcsAction planarBo = new PlanarGeneralWriteWcsAction
                {
                    ObjectType = planarWcsBo.ObjectType,
                    TaskCode = planarWcsBo.TaskCode,
                    ActionType = planarWcsBo.ActionType,
                    EquipmentCode = planarWcsBo.EquipmentCode,
                    ToEquipmentCode = planarWcsBo.ToEquipmentCode,
                    PalletBarcode=planarWcsBo.PalletBarcode,
                    PalletType=planarWcsBo.PalletType,
                    AlrmCode = planarWcsBo.AlrmCode,
                    Reserve = planarWcsBo.Reserve,
                    Reserve2 = planarWcsBo.Reserve2,
                    Reserve3 = planarWcsBo.Reserve3,
                    Reserve4 = planarWcsBo.Reserve4,
                };
                try
                {
                    bool reso = await _plcWriteBoMange.WCSSetPlanerPLCAsync(planarBo);
                    if (reso)
                    {
                        result.IsSucceed = true;
                        result.Message = "成功！";
                    }
                    else
                    {
                        result.IsSucceed = false;
                        result.Message = "失败！";

                    }
                }
                catch (Exception ex)
                {
                    result.IsSucceed = false;
                    result.Message = ex.Message;
                }
            }
            else
            {

                result.IsSucceed = false;
                result.Message = "失败！";
            }


            return result;
        }

        /// <summary>
        /// 写PlanarPLC
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<HeaderResult<bool>> OperatePlanarPlcBoAsync(PlanarGeneralWriteWcsAction planarWcsBo)
        {
            HeaderResult<bool> result = new();
            if (planarWcsBo != null)
            {
                PlanarGeneralWriteWcsAction planarBo = new PlanarGeneralWriteWcsAction
                {
                    ObjectType = planarWcsBo.ObjectType,
                    TaskCode = planarWcsBo.TaskCode,
                    ActionType = planarWcsBo.ActionType,
                    EquipmentCode = planarWcsBo.EquipmentCode,
                    ToEquipmentCode = planarWcsBo.ToEquipmentCode,
                    PalletBarcode = planarWcsBo.PalletBarcode,
                    PalletType = planarWcsBo.PalletType,
                    AlrmCode = planarWcsBo.AlrmCode,
                    Reserve = planarWcsBo.Reserve,
                    Reserve2 = planarWcsBo.Reserve2,
                    Reserve3 = planarWcsBo.Reserve3,
                    Reserve4 = planarWcsBo.Reserve4,
                };
                try
                {
                    bool reso = await _plcWriteBoMange.OperatePlanarPlcBoAsync(planarBo);
                    if (reso)
                    {
                        result.IsSucceed = true;
                        result.Message = "成功！";
                    }
                    else
                    {
                        result.IsSucceed = false;
                        result.Message = "失败！";

                    }
                }
                catch (Exception ex)
                {
                    result.IsSucceed = false;
                    result.Message = ex.Message;
                }
            }
            else
            {

                result.IsSucceed = false;
                result.Message = "失败！";
            }


            return result;
        }

        /// <summary>
        /// 读取监控数据TEST
        /// </summary>
        /// <param name="proName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        [HttpPost]        
        public async Task<List<ProcessModule>> GetMonitorDataTest(string proName_item)
        {
            List<ProcessModule> proDict = new List<ProcessModule>();
            try
            {
                if (!GlobalResource.ProcessModuleDicts.TryGetValue($"{proName_item}", out proDict))
                {
                    _logUtil.Error($"内存中不存在【{proName_item}】-PLC读取监控数据");
                }
            }
            catch (Exception ex)
            {
                _logUtil.Error($"GetMonitorDataTest方法异常：{ex.Message}");
            }

            return proDict;
        }

        /// <summary>
        /// 读取监控数据key
        /// </summary>
        /// <param name="proName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<string> GetMonitorDataKeyTest()
        {

            List<string> strKeys = new List<string>();
            try
            {
                foreach (var item in GlobalResource.ProcessModuleDicts)
                {
                    strKeys.Add(item.Key);
                }  
            }
            catch (Exception ex)
            {
                _logUtil.Error($"GetMonitorDataTest方法异常：{ex.Message}");
            }

            return string.Join(",", strKeys);
        }

    }
}
